import hashlib
import os
import sys
import ctypes
import subprocess
import shutil
import tempfile
import logging
from pathlib import Path
from typing import Optional
import pefile

# 日志回退
try:
    from logger import app_logger as logger
except ImportError:
    log_dir = Path(__file__).parent / "logs"
    log_dir.mkdir(exist_ok=True)
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s',
        handlers=[
            logging.FileHandler(log_dir / "app.log", encoding='utf-8'),
            logging.StreamHandler(sys.stdout)
        ]
    )
    logger = logging.getLogger("App")

def verify_sha256(file_path: Path, expected_hash: str) -> bool:
    if not file_path.exists():
        logger.error(f"[校验] 文件不存在：{file_path}")
        return False
    sha256 = hashlib.sha256()
    try:
        with open(file_path, 'rb') as f:
            for chunk in iter(lambda: f.read(8192), b""):
                sha256.update(chunk)
        actual = sha256.hexdigest().lower()
        expected = expected_hash.lower()
        logger.info(f"[校验] 实际 SHA256: {actual}")
        logger.info(f"[校验] 期望 SHA256: {expected}")
        return actual == expected
    except Exception as e:
        logger.error(f"[校验] 校验失败: {e}", exc_info=True)
        return False

def is_64bit_file(file_path: Path) -> Optional[bool]:
    logger.info(f"[架构识别] 检测文件架构：{file_path.name}（路径：{file_path}）")
    if not file_path.exists() or not file_path.is_file():
        logger.error(f"[架构识别] 文件不存在或不是文件：{file_path}")
        return None
    try:
        pe = pefile.PE(str(file_path))
        machine_type = pe.FILE_HEADER.Machine
        if machine_type == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_AMD64"]:
            logger.info(f"[架构识别] 识别为64位文件")
            return True
        elif machine_type == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_I386"]:
            logger.info(f"[架构识别] 识别为32位文件")
            return False
        else:
            logger.warning(f"[架构识别] 未知架构（Machine类型：{machine_type}）")
            return None
    except pefile.PEFormatError as e:
        logger.error(f"[架构识别] 非PE格式文件：{e}")
        return None
    except Exception as e:
        logger.error(f"[架构识别] 解析失败：{e}", exc_info=True)
        return None

def is_64bit_os() -> bool:
    result = sys.maxsize > 2 ** 32
    logger.info(f"[系统信息] 检测到{'64位' if result else '32位'}操作系统")
    return result

def is_admin() -> bool:
    try:
        result = ctypes.windll.shell32.IsUserAnAdmin()
        logger.info(f"[权限检查] 管理员权限：{'是' if result else '否'}")
        return result
    except:
        logger.warning("[权限检查] 权限检查失败，默认返回非管理员")
        return False

def is_process_running(exe_name: str) -> bool:
    try:
        import psutil
        for proc in psutil.process_iter(['name']):
            if proc.info['name'] == exe_name:
                return True
        return False
    except ImportError:
        output = subprocess.check_output(f'tasklist /FI "IMAGENAME eq {exe_name}"', shell=True, text=True)
        return exe_name in output
    except Exception as e:
        logger.warning(f"检查进程失败: {e}")
        return False

def kill_process_by_name(process_name: str) -> bool:
    try:
        import psutil
        current_pid = os.getpid()
        killed = False
        for proc in psutil.process_iter(['pid', 'name']):
            if proc.info['name'] == process_name and proc.info['pid'] != current_pid:
                proc.kill()
                proc.wait(timeout=3)
                logger.info(f"[退出流程] 已强制终止同名进程 PID {proc.info['pid']}")
                killed = True
        return killed
    except ImportError:
        logger.warning("[退出流程] psutil 未安装，跳过同名进程清理")
        return False
    except Exception as e:
        logger.error(f"[退出流程] kill_process_by_name 异常: {e}")
        return False


def clean_old_mei_tempdirs():
    try:
        temp_dir = Path(tempfile.gettempdir())
        count = 0
        for item in temp_dir.iterdir():
            if item.is_dir() and item.name.startswith("_MEI"):
                if hasattr(sys, '_MEIPASS') and str(item) == sys._MEIPASS:
                    continue
                try:
                    shutil.rmtree(item)
                    count += 1
                except PermissionError:
                    pass
        logger.info(f"[清理] 临时目录清理完成，共删除 {count} 个目录")
    except Exception as e:
        logger.warning(f"[清理] 清理临时目录异常: {e}")


def get_current_version() -> str:
    from config.config import APP_ROOT
    ver_file = APP_ROOT / "version.txt"
    if ver_file.exists():
        try:
            with open(ver_file, 'r', encoding='utf-8') as f:
                return f.read().strip()
        except Exception as e:
            logger.error(f"[版本获取] 读取 {ver_file} 失败: {e}")
    return "1.0.0"